package com.startx.core.mvc;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.startx.core.config.ConfigHolder;
import com.startx.core.mvc.define.RequestMapping;
import com.startx.core.mvc.define.RequestMethod;
import com.startx.core.mvc.factory.MappingFactory;
import com.startx.core.system.config.StartxConfig;
import com.startx.core.system.constants.Constants;
import com.startx.core.system.model.AccessTarget;
import com.startx.core.tools.ClassReader;

/**
 * 接入点初始化
 */
public class AccessMapping {
	
	/**
	 * spring 上下文环境
	 */
	private static ClassPathXmlApplicationContext context;
	
	/**
	 * 启动安装AccessMapping
	 */
	public static void start() {
		
		StartxConfig config = ConfigHolder.getConfig();
		
		if(Objects.isNull(context)) {
			
			if(Objects.isNull(config.getSpringPath())) {
				throw new RuntimeException("Spring配置文件地址未设置");
			}
			
			context = new ClassPathXmlApplicationContext(config.getSpringPath());
		}
		
		if(Objects.isNull(config.getPackages())) {
			throw new RuntimeException("AccessMapping扫描路径未配置");
		}
		
		init(config);
	}

	/**
	 * 初始化AccessMapping
	 */
	private static void init(StartxConfig config) {
		List<Class<?>> classes = ClassReader.getClasses(config.getPackages());
		for (Class<?> clz : classes) {
			
			if(clz.isAnnotationPresent(RequestMapping.class)) {
				
				//反射对象
				Object target = context.getBean(clz);
				
				RequestMapping requestMapping = clz.getAnnotation(RequestMapping.class);
				String[] AccessMappingValues = requestMapping.value();
				Method[] declaredMethods = clz.getDeclaredMethods();
				for(Method method:declaredMethods) {
					
					if(method.isAnnotationPresent(RequestMapping.class)) {
						
						RequestMapping mapping = method.getAnnotation(RequestMapping.class);
						RequestMethod[] requestMethods = mapping.method();
						String[] mappingValues = mapping.value();
						
						if(mappingValues.length <= 0) {
							throw new IllegalArgumentException("请设置方法的RequestMapping值");
						}
						
						StringBuffer buffer;
						
						for(RequestMethod requestMethod:requestMethods) {
							buffer = new StringBuffer();
							buffer.append(requestMethod.name().toUpperCase());
							
							for(String AccessMappingValue:AccessMappingValues) {
								
								buffer.append(Constants.UNDER_LINE).append(AccessMappingValue);
								
								for(String mappingValue:mappingValues) {
									
									buffer.append(mappingValue);
									
									AccessTarget AccessMappingTarget = new AccessTarget();
									AccessMappingTarget.setMethod(method);
									AccessMappingTarget.setObj(target);
									AccessMappingTarget.setType(mapping.type());
									
									MappingFactory.setAccessMapping(buffer.toString(), AccessMappingTarget);
								}
								
							}
							
						}
						
					}
				}
				
			}
		}
	}
	
}
